//      mult.c
//      
//      Copyright 2012 Rafael Asprilla <drakoniss@Asprilla-PC>
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.
//      
//      


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main(int argc, char **argv)
{
	FILE *op1, *op2, *res;
	int s1[2], s2[2], i, j, k;
	time_t curr_time;
	char cmd[512], tmpfn[] = "prcXXXXXX";
	
	if(argc < 6)
	{
		printf("Usage: %s matrix_ixk matrix_kxj part_file start end.\nLast index will be [end-1].\n", argv[0]);
		return 0;
	}
	
	op1 = fopen(argv[1], "rb");
	op2 = fopen(argv[2], "rb");
	
	if((i = mkstemp(tmpfn)) == -1)
		return -5;
		
 	res = fdopen(i, "wb");
	
	if(op1 == NULL)
	{
		time(&curr_time);
		sprintf(cmd, "echo \"%s: Error reading: %s\">>codserver.log", strtok(ctime(&curr_time),"\n"), argv[1]);
		system(cmd);
		return -1;
	}
	
	if(op2 == NULL)
	{
		time(&curr_time);
		sprintf(cmd, "echo \"%s: Error reading: %s\">>codserver.log", strtok(ctime(&curr_time),"\n"), argv[2]);
		system(cmd);
		return -2;
	}
	
	if(res == NULL)
		return -3;
	

	fread(s1, sizeof(int), 2, op1);
	fread(s2, sizeof(int), 2, op2);
	fgetc(op1);
	fgetc(op2);
	
	if(s1[1] != s2[0])
	{
		time(&curr_time);
		sprintf(cmd, "echo \"%s: Wrong sizes. Error in part: %s\">>codserver.log", strtok(ctime(&curr_time),"\n"), argv[3]);
		system(cmd);
		return -4;
	}
		
	float m1[s1[0]][s1[1]], m2[s2[0]][s2[1]];
	for(i = 0; i < s1[0]; i++)
	{
		fread(m1[i], sizeof(float), s1[1], op1);
		fgetc(op1);			
	}
	for(i = 0; i < s2[0]; i++)
	{
		fread(m2[i], sizeof(float), s2[1], op2);
		fgetc(op2);			
	}
	fclose(op1);
	fclose(op2);
	
	float v[s2[1]];
	for(i = atoi(argv[4]); i < atoi(argv[5]); i++)
	{
		for(j = 0; j < s2[1]; j++)
		{
			v[j] = 0;
			for(k = 0; k < s1[1]; k++)
				v[j] += m1[i][k] * m2[k][j];

			
		}			
		fwrite(v, sizeof(float), s2[1], res);
		fputc('\n', res);
	}
	fclose(res);
	rename(tmpfn, argv[3]);
	time(&curr_time);
	sprintf(cmd, "echo \"%s: Success part: %s\">>codserver.log", strtok(ctime(&curr_time),"\n"), argv[3]);
	system(cmd);
	return 0;
}

